package com.ncmmall.application.business.distribution;

import com.ncmmall.application.business.distribution.poster.*;
import com.feijin.commons.domain.Ids;
import com.feijin.commons.lang.PropertiesHelps;
import com.feijin.commons.lang.Requires;
import com.ncmmall.domain.business.distribution.DistributionPoster;
import com.ncmmall.domain.business.distribution.DistributionPosterRepository;
import com.ncmmall.domain.business.goods.Goods;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.collect.Maps;
import com.ncmmall.application.business.distribution.poster.Poster1;
import com.ncmmall.application.business.distribution.poster.Poster2;
import com.ncmmall.application.business.distribution.poster.Poster3;
import com.ncmmall.application.business.distribution.poster.Poster4;
import com.ncmmall.application.business.distribution.poster.Poster5;
import com.ncmmall.application.business.distribution.poster.Poster6;
import com.quaint.poster.core.impl.PosterDefaultImpl;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@Transactional
public class DistributionPosterApplication {

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private DistributionPosterRepository distributionPosterRepository;

    public Map<String, Object> getImage(int posterType, int layout) {

        int type;
        if (posterType == 1 || posterType == 3) {
            if (layout == 1) {
                type = 4;
            } else if (layout == 2) {
                type = 5;
            } else {
                type = 6;
            }
        } else {
            if (layout == 1) {
                type = 1;
            } else if (layout == 2) {
                type = 2;
            } else {
                type = 3;
            }
        }


        Map<String, Object> data = Maps.newHashMap();
        if (type == 1) {
            data.put("nickname_top", "10");
            data.put("nickname_left", "10");
            data.put("avatar_top", "10");
            data.put("avatar_left", "619");
            data.put("goodsName_top", "789");
            data.put("goodsName_left", "10");
            data.put("goodsIamge_top", "780");
            data.put("goodsIamge_left", "388");
            data.put("qrCodeImage_top", "780");
            data.put("qrCodeImage_left", "551");
        } else if (type == 2) {
            data.put("nickname_top", "50");
            data.put("nickname_left", "143");
            data.put("avatar_top", "25");
            data.put("avatar_left", "30");
            data.put("goodsName_top", "789");
            data.put("goodsName_left", "371");
            data.put("goodsIamge_top", "773");
            data.put("goodsIamge_left", "29");
            data.put("qrCodeImage_top", "773");
            data.put("qrCodeImage_left", "196");
        } else if (type == 3) {
            data.put("nickname_top", "800");
            data.put("nickname_left", "30");
            data.put("avatar_top", "800");
            data.put("avatar_left", "616");
            data.put("goodsName_top", "50");
            data.put("goodsName_left", "35");
            data.put("goodsIamge_top", "30");
            data.put("goodsIamge_left", "388");
            data.put("qrCodeImage_top", "30");
            data.put("qrCodeImage_left", "551");
        } else if (type == 4) {
            data.put("nickname_top", "53");
            data.put("nickname_left", "145");
            data.put("avatar_top", "25");
            data.put("avatar_left", "30");
            data.put("goodsName_top", "808");
            data.put("goodsName_left", "208");
            data.put("goodsIamge_top", "0");
            data.put("goodsIamge_left", "0");
            data.put("qrCodeImage_top", "772");
            data.put("qrCodeImage_left", "29");
        } else if (type == 5) {
            data.put("nickname_top", "30");
            data.put("nickname_left", "30");
            data.put("avatar_top", "30");
            data.put("avatar_left", "619");
            data.put("goodsName_top", "810");
            data.put("goodsName_left", "208");
            data.put("goodsIamge_top", "0");
            data.put("goodsIamge_left", "0");
            data.put("qrCodeImage_top", "772");
            data.put("qrCodeImage_left", "30");
        } else {
            data.put("nickname_top", "30");
            data.put("nickname_left", "30");
            data.put("avatar_top", "30");
            data.put("avatar_left", "619");
            data.put("goodsName_top", "0");
            data.put("goodsName_left", "0");
            data.put("goodsIamge_top", "0");
            data.put("goodsIamge_left", "0");
            data.put("qrCodeImage_top", "780");
            data.put("qrCodeImage_left", "30");
        }
        return data;
    }

    private final String storePath = PropertiesHelps.getValue("store.path");

    private final HttpClient httpClient = HttpClients.custom().disableCookieManagement().build();

    /**
     * 获取AccessToken
     */
    private String getAccessToken() throws IOException {

        String appId = PropertiesHelps.getValue("wx.sub_appid");
        String secret = PropertiesHelps.getValue("wx.appSecret");

        HttpResponse response = httpClient.execute(new HttpGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + secret));
        String result = EntityUtils.toString(response.getEntity(), "utf-8");

        JSONObject jsonObject = JSONObject.fromObject(result);

        if (jsonObject.get("errcode") == null || (int) jsonObject.get("errcode") == 0) {
            return (String) jsonObject.get("access_token");
        }
        return "";
    }


    /**
     * 生成小程序码
     */
    public String generateQrcode(String page, String scene) throws Exception {

        String accessToken = getAccessToken();

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("scene", scene);
        jsonObject.put("page", page);
        jsonObject.put("width", 280);

        CloseableHttpClient httpClient = HttpClientBuilder.create().build();

        HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken);

        httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
        StringEntity entity = new StringEntity(jsonObject.toString());
        httpPost.setEntity(entity);

        HttpResponse response = httpClient.execute(httpPost);

        InputStream inputStream = response.getEntity().getContent();

        if (response.getEntity().getContentType().getValue().toLowerCase().contains("json")) {

            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder body = new StringBuilder();
            String temp;
            while ((temp = reader.readLine()) != null) {
                body.append(temp);
            }
            throw new Exception(body.toString());
        }

        File path = new File(storePath + "/code");
        FileUtils.forceMkdir(path);

        String name = System.currentTimeMillis() + ".png";
        FileUtils.copyInputStreamToFile(inputStream, new File(path, name));

        return name;

    }


    public void disable(DistributionPoster poster) {
        poster.setStatus(2);
        distributionPosterRepository.save(poster);
    }

    public void enable(DistributionPoster poster) {
        poster.setStatus(1);
        distributionPosterRepository.save(poster);
    }

    public void disables(List<DistributionPoster> posters) {
        for (DistributionPoster poster : posters) {
            disable(poster);
        }
    }

    public void enables(List<DistributionPoster> posters) {
        for (DistributionPoster poster : posters) {
            if (poster.getStatus() == 2) {
                enable(poster);
            }
        }
    }

    public void remove(DistributionPoster poster) {
        distributionPosterRepository.delete(poster);
    }

    public void removes(List<DistributionPoster> posters) {
        distributionPosterRepository.delete(posters);
    }

    /**
     * 创建海报
     */
    public void create(DistributionPoster poster) {
        poster.setCreateTime(new Timestamp(System.currentTimeMillis()));
        distributionPosterRepository.save(poster);
    }


    public String generatePosterImage(DistributionPoster params, WebUser user) throws IllegalAccessException, IOException {


        BufferedImage background = null;
        BufferedImage goodsImage = null;
        BufferedImage qrCode = null;
        BufferedImage avatar = null;
        BufferedImage image = null;

        try {

            DistributionPoster poster = queryChannelService.findOne(DistributionPoster.class, params.getId());

//            String baseDir = PropertiesHelps.getValue("web.domain") + "/resources/images/";
            if (StringUtils.isNotBlank(user.getAvatar())) {
                avatar = ImageIO.read(new FileInputStream(new File(storePath + "/avatar/" + user.getAvatar())));
            }
            background = ImageIO.read(new FileInputStream(new File(storePath + "/uploads/" + poster.getBackground())));

            String page;
            String scene;

            if (poster.getType() == 1) {
                page = "page/my/pages/applyButor/apply/apply";
                scene = "distributorId=" + user.getDistributor().getId();
            } else if (poster.getType() == 2) {
                page = "pages/index/goodsDetail/goodsDetail";
//                scene = "id=" + params.getGoodsId() + "&type=2&distributorId=" + user.getDistributor().getId() + "&distributorSource=1";
                scene = "id=" + params.getGoodsId() + "&type=2&did=" + user.getDistributor().getId() + "&ds=1";
            } else {
                page = "page/distribution/pages/smallShop/smallShop";
                scene = "distributorId=" + user.getDistributor().getId();
            }

            String imageName;
            try {
                imageName = generateQrcode(page, scene);
            } catch (Exception e) {
                log.error("[生成小程序码异常]", e);
                throw new IllegalArgumentException("生成小程序码异常", e);
            }

            qrCode = ImageIO.read(new FileInputStream(new File(storePath + "/code/" + imageName)));

            String text = poster.getText();
            log.info("原始字符串: {}", text);

            if (StringUtils.isNotBlank(text)) {
                if (text.contains("【$nickname】")) {
                    log.info("$nickname转换前: {}", text);
                    text = StringUtils.replace(text, "【$nickname】", user.getNickname());
                    log.info("$nickname转换后: {}", text);
                }

                if (text.contains("【$shopname】")) {
                    log.info("$shopname转换前: {}", text);
                    text = StringUtils.replace(text, "【$shopname】", user.getDistributor().getShopName());
                    log.info("$shopname转换前: {}", text);
                }
            }

            if (poster.getType() == 1 || poster.getType() == 3) {

                if (poster.getLayout() == 1) {
                    Poster1 poster1 = new Poster1();
                    poster1.setBackgroundImage(background);
                    poster1.setAvatar(avatar);
                    poster1.setNickName(user.getNickname());
                    poster1.setQrCode(qrCode);
                    poster1.setText(text);
                    PosterDefaultImpl<Poster1> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster1).draw(null);
                } else if (poster.getLayout() == 2) {
                    Poster2 poster2 = new Poster2();
                    poster2.setBackgroundImage(background);
                    poster2.setAvatar(avatar);
                    poster2.setNickName(user.getNickname());
                    poster2.setQrCode(qrCode);
                    poster2.setText(text);
                    PosterDefaultImpl<Poster2> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster2).draw(null);
                } else {
                    Poster3 poster3 = new Poster3();
                    poster3.setBackgroundImage(background);
                    poster3.setAvatar(avatar);
                    poster3.setNickName(user.getNickname());
                    poster3.setQrCode(qrCode);
                    poster3.setText(text);
                    PosterDefaultImpl<Poster3> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster3).draw(null);
                }

            } else {

                Requires.notNull(params.getGoodsId(), "商品id不能为空");
                Goods goods = queryChannelService.findOne(Goods.class, params.getGoodsId());
                goodsImage = ImageIO.read(new FileInputStream(storePath + "/uploads/" + goods.getDefaultImage()));

                if (StringUtils.isNotBlank(text) && text.contains("【$productname】")) {
                    log.info("$productname转换前: {}", text);
                    text = StringUtils.replace(text, "【$productname】", goods.getName());
                    log.info("$productname转换后: {}", text);
                }

                if (poster.getLayout() == 1) {
                    Poster4 poster4 = new Poster4();
                    poster4.setBackgroundImage(background);
                    poster4.setAvatar(avatar);
                    poster4.setNickName(user.getNickname());
                    poster4.setGoodsName(goods.getName());
                    poster4.setGoodsImage(goodsImage);
                    poster4.setQrCode(qrCode);
                    poster4.setText(text);
                    PosterDefaultImpl<Poster4> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster4).draw(null);
                } else if (poster.getLayout() == 2) {
                    Poster5 poster5 = new Poster5();
                    poster5.setBackgroundImage(background);
                    poster5.setAvatar(avatar);
                    poster5.setNickName(user.getNickname());
                    poster5.setGoodsName(goods.getName());
                    poster5.setGoodsImage(goodsImage);
                    poster5.setQrCode(qrCode);
                    poster5.setText(text);
                    PosterDefaultImpl<Poster5> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster5).draw(null);
                } else {
                    Poster6 poster6 = new Poster6();
                    poster6.setBackgroundImage(background);
                    poster6.setAvatar(avatar);
                    poster6.setNickName(user.getNickname());
                    poster6.setGoodsName(goods.getName());
                    poster6.setGoodsImage(goodsImage);
                    poster6.setQrCode(qrCode);
                    poster6.setText(text);
                    PosterDefaultImpl<Poster6> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster6).draw(null);
                }

            }


            String fileName = Ids.generateId() + ".jpg";
            ImageIO.write(image, "jpg", new FileOutputStream(new File(storePath + "/uploads/" + fileName)));
            return fileName;

        } finally {
            if (background != null) {
                background.getGraphics().dispose();
            }
            if (goodsImage != null) {
                goodsImage.getGraphics().dispose();
            }
            if (qrCode != null) {
                qrCode.getGraphics().dispose();
            }
            if (avatar != null) {
                avatar.getGraphics().dispose();
            }
            if (image != null) {
                image.getGraphics().dispose();
            }
        }
    }

    /**
     * admin，merchant 生成海报模板预览
     *
     * @param params 海报参数
     * @return 生成图片名称
     */
    public String generateTemplateImage(DistributionPoster params) throws IllegalAccessException, IOException {

        BufferedImage background = null;
        BufferedImage goodsImage = null;
        BufferedImage qrCode = null;
        BufferedImage avatar = null;
        BufferedImage image = null;

        try {

            String baseDir = PropertiesHelps.getValue("web.domain") + "/resources/images/";

            qrCode = ImageIO.read(new URL(baseDir + "qrcode.png").openStream());
            avatar = ImageIO.read(new URL(baseDir + "avatar.png").openStream());
            background = ImageIO.read(new FileInputStream(new File(storePath + "/uploads/" + params.getBackground())));

            if (params.getType() == 1 || params.getType() == 3) {

                if (params.getLayout() == 1) {
                    Poster1 poster1 = new Poster1();
                    poster1.setBackgroundImage(background);
                    poster1.setAvatar(avatar);
                    poster1.setNickName("用户昵称");
                    poster1.setQrCode(qrCode);
                    poster1.setText(params.getText());
                    PosterDefaultImpl<Poster1> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster1).draw(null);
                } else if (params.getLayout() == 2) {
                    Poster2 poster2 = new Poster2();
                    poster2.setBackgroundImage(background);
                    poster2.setAvatar(avatar);
                    poster2.setNickName("用户昵称");
                    poster2.setQrCode(qrCode);
                    poster2.setText(params.getText());
                    PosterDefaultImpl<Poster2> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster2).draw(null);
                } else {
                    Poster3 poster3 = new Poster3();
                    poster3.setBackgroundImage(background);
                    poster3.setAvatar(avatar);
                    poster3.setNickName("用户昵称");
                    poster3.setQrCode(qrCode);
                    poster3.setText(params.getText());
                    PosterDefaultImpl<Poster3> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster3).draw(null);
                }

            } else {

                goodsImage = ImageIO.read(new URL(baseDir + "shop.png").openStream());

                if (params.getLayout() == 1) {
                    Poster4 poster4 = new Poster4();
                    poster4.setBackgroundImage(background);
                    poster4.setAvatar(avatar);
                    poster4.setNickName("用户昵称");
                    poster4.setGoodsName("商品名称");
                    poster4.setGoodsImage(goodsImage);
                    poster4.setQrCode(qrCode);
                    poster4.setText(params.getText());
                    PosterDefaultImpl<Poster4> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster4).draw(null);
                } else if (params.getLayout() == 2) {
                    Poster5 poster5 = new Poster5();
                    poster5.setBackgroundImage(background);
                    poster5.setAvatar(avatar);
                    poster5.setNickName("用户昵称");
                    poster5.setGoodsName("商品名称");
                    poster5.setGoodsImage(goodsImage);
                    poster5.setQrCode(qrCode);
                    poster5.setText(params.getText());
                    PosterDefaultImpl<Poster5> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster5).draw(null);
                } else {
                    Poster6 poster6 = new Poster6();
                    poster6.setBackgroundImage(background);
                    poster6.setAvatar(avatar);
                    poster6.setNickName("用户昵称");
                    poster6.setGoodsName("商品名称");
                    poster6.setGoodsImage(goodsImage);
                    poster6.setQrCode(qrCode);
                    poster6.setText(params.getText());
                    PosterDefaultImpl<Poster6> impl = new PosterDefaultImpl<>();
                    image = impl.annotationDrawPoster(poster6).draw(null);
                }

            }


            String fileName = Ids.generateId() + ".jpg";
            ImageIO.write(image, "jpg", new FileOutputStream(new File(storePath + "/uploads/" + fileName)));
            return fileName;

        } finally {
            if (background != null) {
                background.getGraphics().dispose();
            }
            if (goodsImage != null) {
                goodsImage.getGraphics().dispose();
            }
            if (qrCode != null) {
                qrCode.getGraphics().dispose();
            }
            if (avatar != null) {
                avatar.getGraphics().dispose();
            }
            if (image != null) {
                image.getGraphics().dispose();
            }
        }
    }


    /**
     * 编辑海报
     */
    public void modify(DistributionPoster params) throws IOException {

        DistributionPoster poster = queryChannelService.findOne(DistributionPoster.class, params.getId());

        //todo 如果文字或者背景图片发生改变，需要生成海报
        BufferedImage image = ImageIO.read(new File(storePath + "/uploads/" + params.getBackground()));

        Graphics g = image.getGraphics();
        g.drawString("测试文字", 20, 20);
        g.dispose();

        String name = Ids.generateId() + ".jpg";
        ImageIO.write(image, "jpg", new File(storePath + "/uploads/" + name));

        //删除旧海报
        Files.delete(Paths.get(storePath + "/uploads/" + poster.getImage()));

        poster.setImage(name)
                .setContent(params.getContent())
                .setText(params.getText())
                .setLayout(params.getLayout())
                .setBackground(params.getBackground());
        distributionPosterRepository.save(poster);
    }

    /**
     * 提交审核
     */
    public void applyCheck(DistributionPoster poster) {
        poster.setStatus(4);
        distributionPosterRepository.save(poster);
    }

    /**
     * 审核
     */
    public void check(DistributionPoster params) {
        DistributionPoster poster = queryChannelService.findOne(DistributionPoster.class, params.getId());
        poster.setStatus(params.getStatus())
                .setNote(params.getNote());
        distributionPosterRepository.save(poster);
    }

    /**
     * 批量审核失败
     */
    public void checks(List<DistributionPoster> posters) {
        for (DistributionPoster poster : posters) {
            poster.setStatus(5);
        }
        distributionPosterRepository.save(posters);
    }

}
